home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 6: Level 6 / 17 Bit - Level 6 (1998)(Epic Marketing)[!].iso / quartz / q0429.dms / q0429.adf / libray / libobj / intersect.c < prev    next >
C/C++ Source or Header  |  1991-08-08  |  4KB  |  174 lines

  1. /*
  2.  * intersect.c
  3.  *
  4.  * Copyright (C) 1989, 1991, Craig E. Kolb
  5.  * All rights reserved.
  6.  *
  7.  * This software may be freely copied, modified, and redistributed
  8.  * provided that this copyright notice is preserved on all copies.
  9.  *
  10.  * You may not distribute this software, in whole or in part, as part of
  11.  * any commercial product without the express consent of the authors.
  12.  *
  13.  * There is no warranty or other guarantee of fitness of this software
  14.  * for any purpose.  It is provided solely "as is".
  15.  *
  16.  * $Id: intersect.c,v 4.0 91/07/17 14:38:37 kolb Exp Locker: kolb $
  17.  *
  18.  * $Log:    intersect.c,v $
  19.  * Revision 4.0  91/07/17  14:38:37  kolb
  20.  * Initial version.
  21.  * 
  22.  */
  23. #include "geom.h"
  24.  
  25. static void AddToHitList();
  26. /*
  27.  * Number of bounding volume tests.
  28.  * External modules have read access via IntersectStats().
  29.  */
  30. static unsigned long BVTests;
  31.  
  32. /*
  33.  * Intersect object & ray.  Return distance from "pos" along "ray" to
  34.  * intersection point.  Return value <= 0 indicates no intersection.
  35.  */
  36. int
  37. intersect(obj, ray, hitlist, mindist, maxdist)
  38. Geom *obj;                /* Geom to be tested. */
  39. Ray *ray;                /* Ray origin, direction. */
  40. HitList *hitlist;            /* Intersection path */
  41. Float mindist, *maxdist;
  42. {
  43.     Ray newray;
  44.     Vector vtmp;
  45.     Trans *curtrans;    
  46.     Float distfact, nmindist, nmaxdist;
  47.  
  48.     /*
  49.      * Check ray/bounding volume intersection, if required.
  50.      */
  51.     if (obj->methods->checkbounds) {
  52.         VecAddScaled(ray->pos, mindist, ray->dir, &vtmp);
  53.         if (OutOfBounds(&vtmp, obj->bounds)) {
  54.             nmaxdist = *maxdist;
  55.             BVTests++;
  56.             if (!BoundsIntersect(ray, obj->bounds, mindist,
  57.                             &nmaxdist))
  58.                 return FALSE;
  59.         }
  60.     }
  61.  
  62.     newray = *ray;
  63.     nmindist = mindist;
  64.     nmaxdist = *maxdist;
  65.  
  66.     /*
  67.      * Transform the ray if necessary.
  68.      */
  69.     if (obj->trans != (Trans *)0) {
  70.         /*
  71.          * If object's idea of the current time is wrong,
  72.          * update the transformations.
  73.          */
  74.         if (obj->animtrans && !equal(obj->timenow, ray->time)) {
  75.             TransResolveAssoc(obj->trans);
  76.         }
  77.                 
  78.         /*
  79.          * Transforming the ray can change the distance between
  80.          * the ray origin and the point of intersection.
  81.          * We save the amount the ray is "stretched" and later
  82.          * divide the computed distance by this amount.
  83.          */
  84.         distfact = 1.;
  85.         for (curtrans = obj->transtail; curtrans; 
  86.              curtrans = curtrans->prev)
  87.             distfact *= RayTransform(&newray, &curtrans->itrans);
  88.         nmindist *= distfact;
  89.         nmaxdist *= distfact;
  90.     }
  91.     /*
  92.      * Geom has been updated to current time.
  93.      */
  94.     obj->timenow = ray->time;
  95.  
  96.     /*
  97.      * Call correct intersection routine.
  98.      */
  99.     if (IsAggregate(obj)) {
  100.         /*
  101.          * Aggregate
  102.          */
  103.         if (!(*obj->methods->intersect)
  104.              (obj->obj, &newray, hitlist, nmindist, &nmaxdist))
  105.         return FALSE;
  106.     } else {
  107.         /*
  108.          * Primitive
  109.          */
  110.         if (!(*obj->methods->intersect)
  111.               (obj->obj, &newray, nmindist, &nmaxdist))
  112.             return FALSE;
  113.         hitlist->nodes = 0;
  114.     }
  115.  
  116.     /*
  117.      * Had a hit -- add ray, distance and object to tail of hitlist.
  118.      */
  119.     AddToHitList(hitlist, &newray, nmindist, nmaxdist, obj);
  120.  
  121.     /*
  122.      * Set dist to distance to intersection point from the origin
  123.      * of the untransformed ray.
  124.      */
  125.     if (obj->trans != (Trans *)0)
  126.         *maxdist = nmaxdist / distfact;
  127.     else
  128.         *maxdist = nmaxdist;
  129.  
  130.     return TRUE;
  131. }
  132.  
  133. static void
  134. AddToHitList(hitlist, ray, mind, dist, obj)
  135. HitList *hitlist;
  136. Ray *ray;
  137. Float mind, dist;
  138. Geom *obj;
  139. {
  140.     HitNode *np;
  141.     Trans *list;
  142.  
  143.     np = &hitlist->data[hitlist->nodes++];
  144.  
  145.     np->ray = *ray;
  146.     np->obj = obj;
  147.     np->mindist = mind;
  148.     np->dist = dist;
  149.     np->enter = 0;
  150.  
  151.     if (obj->trans) {
  152.         /*
  153.          * Compute total transformation, forward and inverse,
  154.          * for this object, and store in hitlist for use later.
  155.          */
  156.         TransCopy(obj->trans, &np->trans);
  157.         for (list = obj->trans->next; list; list = list->next)
  158.             TransCompose(&np->trans, list, &np->trans);
  159.         np->dotrans = TRUE;
  160.     } else
  161.         np->dotrans = FALSE;
  162. }
  163.  
  164. /*
  165.  * Return intersection statistics.
  166.  * Currently, this is limited to the # of bounding volume test performed.
  167.  */
  168. void
  169. IntersectStats(bvtests)
  170. unsigned long *bvtests;
  171. {
  172.     *bvtests = BVTests;
  173. }
  174.